package com.tskj.mh.badminton.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tskj.mh.badminton.aop.annotation.SystemControllerLog;
import com.tskj.mh.badminton.dao.BadmintonDAO;
import com.tskj.mh.badminton.quene.BadmintonQuene;
import com.tskj.mh.badminton.quene.QueneItemInfo;
import com.tskj.mh.badminton.utility.ModuleType;
import com.tskj.mh.badminton.utility.Tools;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * @author LeonSu
 */
@Service
public class BadmintonService {

    @Autowired
    private BadmintonDAO badmintonDAO;

    public JSONArray getRoomList() {
        return badmintonDAO.getBadmintonRoomList();
    }

    public JSONArray getTimeList(String badmintonId, String date) {
        JSONArray allList = badmintonDAO.getTimeAndCountList(badmintonId, date);
        JSONArray retArray = new JSONArray();
        JSONObject data;
        for (Object obj : allList) {
            JSONObject json = (JSONObject) obj;
            data = new JSONObject();
            data.put("id", json.getString("tid"));
            data.put("timeTitle", String.format("%s - %s", Tools.getShortTime(json.getString("starttime")), Tools.getShortTime(json.getString("endtime"))));
            data.put("timeCount", json.getIntValue("bnum"));
            retArray.add(data);
        }
        return retArray;
    }

    @Autowired
    private BadmintonQuene badmintonQuene;

    public JSONObject saveOrderToQuene(String userToken, JSONObject student, JSONObject data) {
        QueneItemInfo itemInfo = new QueneItemInfo(userToken, student, data);
        badmintonQuene.push(itemInfo);
        JSONObject ret = new JSONObject();
        ret.put("code", 0);
        return ret;
    }

    @Transactional(rollbackFor = Exception.class)
    public JSONObject saveOrder(JSONObject student, JSONObject data) throws Exception {
        JSONObject retData = new JSONObject();

//        String timeId = data.getString("id");
        String badmintonRoom = data.getString("BadmintonRoom");
        String badmintonRoomId = data.getString("BadmintonId");
        String newBadmintonRoomId = badmintonDAO.getBadmintonRoomId(badmintonRoom);
        if (!newBadmintonRoomId.equalsIgnoreCase(badmintonRoomId)) {
            throw new RuntimeException("数据不正确");
        }

        String dateString = data.getString("date");
        JSONArray timeString = data.getJSONArray("time");

        String sex = student.getString("sexy");
        int sexId = sex.equals("男") ? 1 : 0;
        String studentName = student.getString("studentname");
        String studentNo = student.getString("studentid");
        String xueYuan = student.getString("xueyuan");
        String adUserName = student.getString("username");
        String roomSortNo = badmintonDAO.getRoomSortNo(badmintonRoomId, badmintonRoom);
        String timeSortNo;
        String maxOrderNo;
        int studentCount = data.getInteger("count");
        String code;
        String startTime;
        String endTime;

        //TODO：保存前，需要检查当前用户是否已有未完成订单
        if (badmintonDAO.hasOrder(adUserName, Tools.today())) {
            throw new Exception("订单超额");
//            retData.put("code", 1);
//            retData.put("errMsg","订单超额");
//            return retData;
        }

        boolean allSaved = false;
        List<String> retCode = new ArrayList<>();
        for (Object obj : timeString) {
            startTime = obj.toString().split("-")[0].trim();
            endTime = obj.toString().split("-")[1].trim();

            if (badmintonDAO.isClosed(badmintonRoomId, startTime, endTime)) {
                throw new Exception(badmintonRoom + " 已关闭");
            }

            //TODO:保存前，需要检查当前时间是否已订满
            if (!badmintonDAO.canSave(badmintonRoom, startTime, endTime, 1, dateString)) {
                throw new Exception("订单已满");
//                    retData.put("code", 1);
//                    retData.put("errMsg","订单已满");
//                    return retData;
            }

            //TODO：保存前，需要检查当前用户是否已有同预约日期与预约时间的乒乓球未完成订单
            if (badmintonDAO.hasTableTennisOrder(adUserName, dateString, startTime)) {
                throw new Exception("同一时间（"+startTime+"）已有乒乓球订单");
//                    retData.put("code", 1);
//                    retData.put("errMsg","已有乒乓球订单");
//                    return retData;
            }

            timeSortNo = badmintonDAO.getTimeSortNo(badmintonRoomId, startTime, endTime);
            maxOrderNo = badmintonDAO.getMaxOrderNo(badmintonRoom, dateString, startTime, endTime);
            code = String.format("%s-%s-%04d-%d", roomSortNo, timeSortNo, Integer.valueOf(maxOrderNo), studentCount);

            badmintonDAO.save(Tools.newId(), studentName, sex, Integer.valueOf(maxOrderNo), badmintonRoom, startTime, endTime, 0, code, dateString, adUserName, studentCount, xueYuan);
            retCode.add(code);
            allSaved = true;
        }

        if (!allSaved) {
            throw new Exception("订单错误");
//            retData.put("code", 1);
//            retData.put("errMsg", StringUtils.join(retCode, ","));
//            return retData;
        }

        retData.put("code", 0);
        JSONObject detail = new JSONObject();
        retData.put("data", detail);
        student = new JSONObject();
        student.put("name", studentName);
        student.put("no", studentNo);
        student.put("xueyuan", xueYuan);
        student.put("sex", sex);
        detail.put("student", student);

        JSONObject order = new JSONObject();
        order.put("type", ModuleType.YU_MAO_QIU.ordinal());
        order.put("address", badmintonRoom);
        order.put("date", dateString);
        order.put("time", StringUtils.join(timeString.toArray(), ","));
        order.put("code", Tools.Encrypt(StringUtils.join(retCode, ",")));
        order.put("count", studentCount);
        detail.put("order", order);
        return retData;
    }

    /**
     * 最大订单数
     */
    private final int MAX_ORDER_COUNT = 2;

    /**
     * 检查是否允许下订单，一是：8:00-16:00能下，二是如果该用户没有下过明天的订单，
     *
     * @param userName
     * @param date
     * @return
     */
    public JSONObject checkStopTime(String userName, String date) {
        JSONObject ret = new JSONObject();
        ret.put("code", 0);
        String time = Tools.getNowTime();
        JSONObject setTimes = badmintonDAO.getStartTime();
        System.out.println(setTimes.toJSONString());
        if (time.compareTo(setTimes.getString("start")) < 0 || time.compareTo(setTimes.getString("end")) > 0) {
            ret.put("data", false);
            ret.put("start", setTimes.getString("start"));
            ret.put("end", setTimes.getString("end"));
        } else {
            if (badmintonDAO.getOrderByAdUserName(userName, date) >= MAX_ORDER_COUNT) {
                ret.put("data", false);
            } else {
                ret.put("data", true);
            }
        }
        return ret;
    }

    public JSONArray getUnFinishedOrder(String adUserName) {
        return badmintonDAO.getUnFinishedOrder(adUserName);
    }

    public JSONArray getFinishedOrder(String adUserName) {
        return badmintonDAO.getFinishedOrder(adUserName);
    }

    public JSONArray getAllOrder(String adUserName) {
        return badmintonDAO.getAllOrder(adUserName);
    }

    public void confirmOrder(String adUserName, String id) throws Exception {
        if (badmintonDAO.getCanConfirm(id)) {
            badmintonDAO.confirmOrder(adUserName, id);
        } else {
            throw new Exception("订单确认失败，未到允许订单确认时间");
        }
    }

    public void cancelOrder(String adUserName, String id) throws Exception {
        if (badmintonDAO.getCanCancel(id)) {
            badmintonDAO.cancelOrder(adUserName, id);
        } else {
            throw new Exception("订单取消失败，超过订单取消时间");
        }
    }

}
